package com.example.bankingsystemandroid;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;

import com.example.bankingsystemandroid.Holder.InfoHolder;
import com.example.bankingsystemandroid.utils.EncryptionUtil;
import com.example.bankingsystemandroid.utils.PropertiesConfig;
import com.example.bankingsystemandroid.utils.PropertyManager;

public class LoginActivity extends Activity {
	private EditText userNameEditText;
	private EditText passwordEditText;
	private EditText captchaEditText;
	private static ImageView imageView;
	private Bitmap captchaBitmap;
	private ImageButton reloadCaptchaButton;
	private Button signInButton;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		GetCaptchaTask captchaTask = new GetCaptchaTask();
		captchaTask.execute();
		super.onCreate(savedInstanceState);
		setContentView(R.layout.login);
		
		userNameEditText = (EditText) findViewById(R.id.userName);
		passwordEditText = (EditText) findViewById(R.id.password);
		captchaEditText = (EditText) findViewById(R.id.captcha);
		imageView = (ImageView) findViewById(R.id.imageViewCaptcha);
		reloadCaptchaButton = (ImageButton) findViewById(R.id.btnReloadCaptcha);
		signInButton = (Button) findViewById(R.id.btnSignIn);

		reloadCaptchaButton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View arg0) {
				reloadCaptchaButton.setActivated(false);
				GetCaptchaTask captchaTask = new GetCaptchaTask();
				captchaTask.execute();
			}
		});

		signInButton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View arg0) {		
				

				String userName = userNameEditText.getText().toString();
				String password = passwordEditText.getText().toString();
				String captchaString = captchaEditText.getText().toString();
				if (!isValidUserName(userName)) {
					userNameEditText.setError("Invalid Username");
				} else if (!isValidPassword(password)) {
					passwordEditText.setError("Invalid Password");
				} else if (captchaString.length() < 1) {
					captchaEditText.setError("Captcha Empty");
				} else {
					try {
						InfoHolder.setUsername(userName);
						InfoHolder.setPassword(EncryptionUtil
								.generateMD5HashFromString(password));

						// endcode
						ArrayList<NameValuePair> postParameters;
						postParameters = new ArrayList<NameValuePair>();
						postParameters.add(new BasicNameValuePair("username",
								userName));
						postParameters.add(new BasicNameValuePair("password",
								EncryptionUtil
										.generateMD5HashFromString(password)));
						postParameters.add(new BasicNameValuePair("jcaptcha",
								captchaString));
						signInButton.setActivated(false);
						LoginTask loginTask = new LoginTask();
						loginTask.execute(postParameters);
						
					} catch (Exception e) {
						// TODO: handle exception
					}
				}
			}
		});
	}	

	// validating username
	private boolean isValidUserName(String userName) {
		if (userName != null && userName.length() >= 5) {
			return true;
		}
		return false;

	}

	// validating password with retype password
	private boolean isValidPassword(String pass) {
		if (pass != null && pass.length() >= 5) {
			return true;
		}
		return false;
	}

	private void showCaptcha(Bitmap bmp) {
		imageView = (ImageView) findViewById(R.id.imageViewCaptcha);
		imageView.setImageBitmap(bmp);
	}

	private class GetCaptchaTask extends AsyncTask<Void, Void, Void> {

		@Override
		protected void onPostExecute(Void result) {
			reloadCaptchaButton.setActivated(true);
			showCaptcha(captchaBitmap);
			super.onPostExecute(result);
		}

		@Override
		protected Void doInBackground(Void... params) {
//			if (SplashScreenActivity.isURLReachable(LoginActivity.this)) {
//				
//			} else {
//				//server not response
//				new AlertDialog.Builder(LoginActivity.this)
//				.setMessage("Server is not response, please try again later!")
//				.setCancelable(false)
//				.setPositiveButton("Exit",
//						new DialogInterface.OnClickListener() {
//							public void onClick(DialogInterface dialog,
//									int id) {
//								finish();
//							}
//						}).show();
//			}
			
			/*
			 * Create the POST request
			 */
			HttpClient httpClient = new DefaultHttpClient();
			String serverIP = PropertiesConfig
					.getProperty(PropertyManager.SERVER_IP);
			String serverPort = PropertiesConfig
					.getProperty(PropertyManager.SERVER_PORT);

			HttpPost httpPost = new HttpPost("http://" + serverIP + ":"
					+ serverPort + "/bankingsystem/jcaptcha.jpg");

			/*
			 * Execute the HTTP Request
			 */
			try {
				HttpResponse response = httpClient.execute(httpPost);				
				HttpEntity respEntity = response.getEntity();
				Header[] headers = response.getAllHeaders();
				for (Header header : headers) {
					if ("Set-Cookie".equals(header.getName())) {
						String headerValue = header.getValue();
						InfoHolder.setSessionId(headerValue.substring(
								headerValue.indexOf("=") + 1,
								headerValue.indexOf(";")));
						Log.i("HeaderName", "Header name: " + header.getName());
						Log.i("HeaderValue",
								"Header value: " + header.getValue());
					}
				}

				if (respEntity != null) {
					// EntityUtils to get the response content
					InputStream inputStream = respEntity.getContent();

					ByteArrayOutputStream buffer = new ByteArrayOutputStream();

					int nRead;
					byte[] data = new byte[1024];

					while ((nRead = inputStream.read(data, 0, data.length)) != -1) {
						buffer.write(data, 0, nRead);
					}
					buffer.flush();
					buffer.toByteArray();
					captchaBitmap = BitmapFactory.decodeByteArray(
							buffer.toByteArray(), 0,
							buffer.toByteArray().length);
				} else {
					//server not response
					new AlertDialog.Builder(LoginActivity.this)
					.setMessage("Server is not response, please try again later!")
					.setCancelable(false)
					.setPositiveButton("Exit",
							new DialogInterface.OnClickListener() {
								public void onClick(DialogInterface dialog,
										int id) {
									finish();
								}
							}).show();
				}
			} catch (ClientProtocolException e) {
				// writing exception to log
				e.printStackTrace();
			} catch (IOException e) {
				// writing exception to log
				e.printStackTrace();
			}
			return null;
		}
	}

	private class LoginTask extends AsyncTask<ArrayList<NameValuePair>, Void, String>{

		@Override
		protected void onPostExecute(String result) {
			
			super.onPostExecute(result);
			if (!"".equals(InfoHolder.getToken())) {
				startActivity(new Intent(getApplicationContext(), MainActivity.class).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
				finish();
			} else {
				signInButton.setActivated(true);
				GetCaptchaTask captchaTask = new GetCaptchaTask();
				captchaTask.execute();
				if ("CAPTCHA_NOT_MATCH".equals(result)) {				
					new AlertDialog.Builder(LoginActivity.this)
					.setMessage("Captcha not match")
					.setCancelable(false)
					.setPositiveButton("Retry",
							new DialogInterface.OnClickListener() {
								public void onClick(DialogInterface dialog,
										int id) {
									captchaEditText.setText("");
								}
							}).show();
				} else if ("INVALID_USERNAME_OR_PASSWORD".equals(result)) {
					new AlertDialog.Builder(LoginActivity.this)
					.setMessage("Invalid Username or Password!")
					.setCancelable(false)
					.setPositiveButton("Retry",
							new DialogInterface.OnClickListener() {
								public void onClick(DialogInterface dialog,
										int id) {
									userNameEditText.setText("");
									passwordEditText.setText("");
									captchaEditText.setText("");
								}
							}).show();
				} else if ("USER_IS_LOCKED".equals(result)) {
					new AlertDialog.Builder(LoginActivity.this)
					.setMessage("Your account has been locked! please try again later!")
					.setCancelable(false)
					.setPositiveButton("Exit",
							new DialogInterface.OnClickListener() {
								public void onClick(DialogInterface dialog,
										int id) {
									finish();
								}
							}).show();
				}
			}			
		}

		@Override
		protected String doInBackground(ArrayList<NameValuePair>... params) {
			/*
			 * Create the POST request
			 */
			HttpClient httpClient = new DefaultHttpClient();
			String serverIP = PropertiesConfig.getProperty(PropertyManager.SERVER_IP);
			String serverPort = PropertiesConfig.getProperty(PropertyManager.SERVER_PORT);
			
			HttpPost httpPost = new HttpPost("http://"+serverIP+":"+serverPort+"/bankingsystem/j_spring_security_check");
			try {
				httpPost.setEntity(new UrlEncodedFormEntity(params[0]));
			} catch (UnsupportedEncodingException e2) {
				e2.printStackTrace();
			}		
			/*
			 * Execute the HTTP Request
			 */
			try {			
				httpPost.addHeader("Cookie", "JSESSIONID=" + InfoHolder.getSessionId());
				
				HttpResponse response = httpClient.execute(httpPost);
			    HttpEntity respEntity = response.getEntity();
			    if(respEntity != null) {
			    	InfoHolder.clearInfo();
					try {
						Header[] headers = response.getAllHeaders();
						for (Header header : headers) {
							if ("Set-Cookie".equals(header.getName())) {
								String headerValue = header.getValue();
								InfoHolder.setSessionId(headerValue.substring(
										headerValue.indexOf("=") + 1,
										headerValue.indexOf(";")));
								Log.i("HeaderName", "Header name: " + header.getName());
								Log.i("HeaderValue",
										"Header value: " + header.getValue());
							}
						}
						
						String retSrc = EntityUtils.toString(respEntity);
						JSONObject result = new JSONObject(retSrc);
						String token = result.getString("token");
						
						if (!"null".equals(token)) {
							InfoHolder.setToken(token);
							InfoHolder.setUsername(userNameEditText.getText().toString());
						} else {
							String errorCode = result.getString("errorCode");
							return result.getString("errorCode");							
						}					
						Log.i("test", token);
					} catch (ParseException e) {
						e.printStackTrace();
					} catch (IllegalStateException e) {
						e.printStackTrace();
					}
					catch (JSONException e) {
						e.printStackTrace();
					}
					// {"token":"414b64a3-0b3e-4f0e-b1df-868d70b71bf9","loginId":"test04","errorCode":null,"errorMsg":null}
					// {"token":null,"loginId":null,"errorCode":"CAPTCHA_NOT_MATCH","errorMsg":"Captcha not match."}
				} else {
					//server not response
					new AlertDialog.Builder(LoginActivity.this)
					.setMessage("Server is not response, please try again later!")
					.setCancelable(false)
					.setPositiveButton("Exit",
							new DialogInterface.OnClickListener() {
								public void onClick(DialogInterface dialog,
										int id) {
									finish();
								}
							}).show();
				}
			    
			} catch (ClientProtocolException e) {
			    // writing exception to log
			    e.printStackTrace();
			} catch (IOException e) {
			    // writing exception to log
			    e.printStackTrace();
			}
			return null;
		}	
	}
}